<template>
  <view class="category-box">
    <!-- 左侧滚动条 -->
    <scroll-view class="scroll-left" scroll-y :scroll-top="leftScrollTop" scroll-with-animation>
      <view
        class="category-item"
        :class="{ 'category-active': index === activeIndex }"
        v-for="(category, index) in data"
        :key="index"
        @click="changeCategory(index)"
      >
        {{ category.name }}
      </view>
    </scroll-view>

    <!-- 右侧滚动条 -->
    <scroll-view
      class="scroll-right"
      scroll-y
      :scroll-top="rightScrollTop"
      scroll-with-animation
      @scroll="onRightScroll"
    >
      <view class="content-group" v-for="(category, index) in data" :key="index">
        <text class="category-name">{{ category.name }}</text>

        <view class="content-list">
          <!-- <view class="content-item" v-for="(goods, idx) in category.category_goods" :key="idx">
            <image class="content-img" mode="aspectFit" :src="goods.goods_logo" :alt="goods.goods_name" />
            <text class="content-name">{{ goods.goods_name }}</text>
          </view> -->
          <view
            class="goods-box"
            v-for="(item, idx) in category.category_goods"
            :key="idx"
            @click="nav.jump('/pages/goods/detail?id=' + item.id)"
          >
            <view class="img-zone">
              <image class="goods-logo" mode="aspectFill" :src="item.goods_logo"></image>
            </view>

            <view class="text-zone">
              <view class="goods-title line-2">{{ item.goods_name }}</view>
              <view class="flex justify-between items-baseline">
                <mt-format-money
                  class="goods-price"
                  :money="parseFloat(item.goods_specs[0].goods_price).toFixed(2)"
                ></mt-format-money>
              </view>
            </view>
          </view>
        </view>
      </view>
      <view class="h-300rpx"></view>
    </scroll-view>
  </view>
</template>

<script lang="ts" setup>
  import mtFormatMoney from '@/components/mt-format/mt-format-money.vue';
  import { ref, getCurrentInstance, nextTick } from 'vue';
  import { nav } from '@/utils/homer';
  import type { CategoryGoodsList } from '@/types/goods';

  const props = withDefaults(
    defineProps<{
      menuHeight?: number;
      itemHeight?: number;
      sliderColor?: string;
      offsetActiveTop?: number;
      offsetActiveBottom?: number;
    }>(),
    {
      menuHeight: 0,
      itemHeight: 45,
      offsetActiveTop: 50,
      offsetActiveBottom: 120,
    }
  );

  const data = ref<CategoryGoodsList[]>([]);
  const _this = getCurrentInstance();
  const sidebarHeight = ref<number>(props.menuHeight);

  const activeIndex = ref<number>(0);
  let nextIndex = 0;
  let maxIndex = 0;

  const leftScrollTop = ref<number>(0);
  const rightScrollTop = ref<number>(0);
  let leftDomsTop = <number[]>[];
  let rightDomsTop = <number[]>[];

  const setSidebarData = (list: CategoryGoodsList[]) => {
    data.value = list;
    maxIndex = data.value.length - 1;

    nextTick(() => {
      let searchHeight = 0;
      let query = uni.createSelectorQuery().in(_this);

      query
        .selectAll('.category-item')
        .boundingClientRect((data: any) => {
          searchHeight = data[0].top;
          if (sidebarHeight.value == 0) {
            uni.getSystemInfo({
              success(res) {
                sidebarHeight.value = res.windowHeight - searchHeight;
              },
            });
          }

          leftDomsTop = data.map((v: any) => v.top - searchHeight);
        })
        .exec();

      query = uni.createSelectorQuery().in(_this);
      query
        .selectAll('.content-group')
        .boundingClientRect((data: any) => {
          rightDomsTop = data.map((v: any) => v.top - searchHeight);
        })
        .exec();
    });
  };

  const searchData = (key: string) => {
    if (!key) {
      changeCategory(0);
    } else {
      data.value.some((category, index) => {
        return category.category_goods.some((goods) => {
          if (goods.goods_name.includes(key)) {
            changeCategory(index);
            return true;
          }

          return false;
        });
      });
    }
  };

  defineExpose({
    setSidebarData,
    searchData,
  });

  // 选择分类
  const changeCategory = (index: number) => {
    activeIndex.value = index;
    rightScrollTop.value = rightDomsTop[index];
  };

  // 联动分类
  const connectCategory = (index: number) => {
    activeIndex.value = index;
    leftScrollTop.value = leftDomsTop[index];
  };

  // 监听右侧滚动条滚动高度，联动左侧分类
  const onRightScroll = async (e: any) => {
    if (e.detail.deltaY < 0) {
      nextIndex = activeIndex.value + 1;
      if (nextIndex > maxIndex) {
        nextIndex = maxIndex;
      }
      if (e.detail.scrollTop >= rightDomsTop[nextIndex] - props.offsetActiveTop) {
        connectCategory(nextIndex);
      }
    } else {
      nextIndex = activeIndex.value - 1;
      if (nextIndex < 0) {
        nextIndex = 0;
      }
      if (e.detail.scrollTop <= rightDomsTop[nextIndex] + props.offsetActiveBottom) {
        connectCategory(nextIndex);
      }
    }
  };
</script>

<style lang="scss" scoped>
  $bgColor: #f6f6f6;

  .category-box {
    display: flex;
    height: v-bind("sidebarHeight + 'px'");
    box-sizing: border-box;
  }

  .scroll-left {
    display: flex;
    flex-direction: column;
    background: #fff;
    flex: 2;

    .category-item {
      display: flex;
      align-items: center;
      justify-content: center;
      height: v-bind("itemHeight + 'px'");
      font-size: 26rpx;
      padding-left: 48rpx;
      padding-right: 20rpx;
      transition: font-size 0.3s;
    }
    .category-item.category-active {
      position: relative;
      background: $bgColor;
      font-size: 28rpx;
      font-weight: 600;

      &::before {
        content: '';
        width: 3px;
        height: 16px;
        background: v-bind(sliderColor);
        left: 12px;
        position: absolute;
      }
    }
  }

  .scroll-right {
    display: flex;
    flex-direction: column;
    flex: 4;
    background: $bgColor;
    // background: lightgreen;

    .content-group {
      padding: 0 23rpx 120rpx;

      .category-name {
        display: flex;
        font-size: 28rpx;
        font-weight: 700;
        padding-top: 25rpx;
      }

      .content-list {
        display: flex;
        justify-content: space-between;
        flex-wrap: wrap;

        .goods-box {
          display: flex;
          flex-direction: column;
          background: white;
          width: 220rpx;
          overflow: hidden;
          margin-top: 30rpx;
          margin-bottom: 20rpx;
          border-radius: 15rpx;

          .img-zone {
            .goods-logo {
              height: 220rpx;
              width: 100%;
            }
          }

          .text-zone {
            padding: 12rpx 15rpx;

            .goods-title {
              font-size: 24rpx;
              margin-bottom: 8rpx;
              line-height: 35rpx;
              letter-spacing: 1rpx;
              height: 70rpx;
            }

            .goods-price {
              color: $themeColor;
              font-size: 32rpx;
              font-weight: 600;

              &::before {
                content: '￥';
                font-size: 20rpx;
                font-weight: 600;
              }
            }

            .market-price {
              color: gray;
              text-decoration: line-through;
              font-size: 22rpx;
              &::before {
                content: '￥';
              }
            }
          }
        }
      }
    }
  }
</style>
